package labb1.fordjupn;

import labb1.del2.Card;
import labb1.del2.NoSuchCardException;

import java.util.ArrayList;

/**
 * @author Mikko Puustinen (mikko.puustinen@gmail.com)
 * @version 0.1, 2007-nov-01
 */
public class PlayerFactory {
    private ArrayList<Player> players;

    /**
     * Creates a new PlayerFactory.
     */
    public PlayerFactory() {
        players = new ArrayList<Player>();
    }

    /**
     * Adds a Player with the chosen name to the list.
     *
     * @param name the name of the Player.
     *
     * @return true if the Player was added correctly, false if the user already
     *         exist.
     */
    public boolean addPlayer(String name) {
        name = name.trim();
        for (Player p : players) {
            if (p.getName().matches("(?i)" + name))
                return false;
        }
        players.add(new HumanPlayer(name));
        return true;
    }

    /**
     * Adds a ComputerPlayer to the game. This Player will have some simple
     * logic for choosing the Card and so on.
     */
    public void addComputer() {
        players.add(new ComputerPlayer());
    }

    /**
     * Removes the chosen player from the list of Players.
     *
     * @param name the name of the Player to remove.
     *
     * @return true if the Player was removed, false otherwise.
     */
    public boolean removePlayer(Object name) {
        for (Player p : players) {
            if (p.getName().equals(name)) {
                return players.remove(p);
            }
        }
        return false;
    }

    /**
     * Get all the Cards the Player has in the hand represented as String
     * values.
     *
     * @return all the Cards as String values.
     */
    public String[] getPlayerCards(int currentPlayer) {
        Player p = players.get(currentPlayer);
        String[] cards = new String[p.getNoOfCard()];
        int i = 0;
        p.sort();
        for (Card card : p.getAllCards()) {
            cards[i] = "(" + card.getSuitString() + ") " + card.getValueString();
            i++;
        }

        return cards;
    }

    /**
     * Get all the Cards the Player has.
     *
     * @param currentPlayer the Player to get the Cards from.
     *
     * @return a clone of all the Cards the Player has.
     */
    public ArrayList getAllCards(int currentPlayer) {
        Player p = players.get(currentPlayer);
        p.sort();
        return p.getAllCards();
    }

    /**
     * @param currentPlayer the Player to get the card value from.
     * @param index         the index of the card to get the value of.
     *
     * @return the value.
     *
     * @throws NoSuchCardException if the index is out of bounds.
     */
    public int getCardValueAt(int currentPlayer, int index) throws NoSuchCardException {
        return players.get(currentPlayer).showCard(index).getValue();
    }

    /**
     * Get all the names of the Players added to the game.
     *
     * @return the name of the Players added in a String array.
     */
    public String[] getAllPlayerNames() {
        String[] names = new String[players.size()];

        int i = 0;
        for (Player p : players) {
            names[i] = p.getName();
            if (p instanceof ComputerPlayer)
                names[i] += " (CPU)";
            i++;
        }

        return names;
    }

    /**
     * Get all the Players.
     *
     * @return a clone of the list containing all the Players.
     */
    public ArrayList<Player> getAllPlayers() {
        ArrayList<Player> clone = new ArrayList<Player>();
        clone.addAll(players);

        return clone;
    }

    /**
     * Get how many times each Player has won the game. The result is put in an
     * int array where the index matches their position in the game list.
     *
     * @return all the wins.
     */
    public int[] getAllPlayerWins() {
        int[] wins = new int[players.size()];
        int i = 0;

        for (Player p : players) {
            wins[i] = p.getWins();
            i++;
        }

        return wins;
    }

    /**
     * Get the number of Players added to the game.
     *
     * @return number of Players added to the game.
     */
    public int numberOfPlayers() {
        return players.size();
    }

    /**
     * Get the name of the Player at the index.
     *
     * @param index the position of the Player.
     *
     * @return the name of the Player as a String.
     *
     * @throws IndexOutOfBoundsException if the specified index is out of
     *                                   bounds.
     */
    public String getPlayerNameAt(int index) throws IndexOutOfBoundsException {
        return players.get(index).getName();
    }

    /**
     * Get the Player at the specified index.
     *
     * @param index the position of the Player.
     *
     * @return the Player.
     *
     * @throws IndexOutOfBoundsException if the specified index is out of
     *                                   bounds.
     */
    public Player getPlayerAt(int index) throws IndexOutOfBoundsException {
        return players.get(index);
    }
}
